<script setup>
import {typeOptions} from "../../../utils/listData.js";
import {computed, nextTick, ref} from "vue";
import {getRequestData} from "../../../utils/getData.js";
import {filterStockList, notify} from "../../../utils/commonScript.js";
import CEchartsStock from "../../../c-components/c-echarts-stock.vue";
import {GET, POST} from "../../../api/index.js";
import {useStore} from "vuex";
import CCard from "../../../c-components/c-card.vue";
import CText from "../../../c-components/c-text.vue";
import CLCandlestick from "../../../utils/CLCandlestick.js";
import EchartsOption from "../../../utils/EchartsOption.js";

const store = useStore()

const baseInfo = computed(() => {
  return store.state.baseInfo;
})

const typeValue = ref('30')
const stockCode = ref('')
const speed = ref(5)
const oldLines = ref([])
const kLines = ref([])
const echartsRef = ref(null)
const timer = ref(null)
const isStart = ref(false)
const currentLine = ref(null)
const initAmount = ref(50000)
const amount = ref(50000)
const stockNum = ref(0)
const tradeNum = ref(100)
const tradeList = ref([])
const n = 240

const availablePurchase = computed(() => {
  return currentLine.value ? parseInt(parseInt(amount.value / currentLine.value.close) / 100) * 100 : 0
})

// 保存交易
const saveTrain = () => {
  console.log(JSON.stringify(oldLines.value))

  POST('/market/train', {
    stockCode: stockCode.value,
    initAmount: initAmount.value,
    endAmount: amount.value,
    level: typeValue.value,
    trainRecordDTOList: tradeList.value,
    lineData: JSON.stringify(oldLines.value),
    rise: amount.value -initAmount.value,
    ratio: ((amount.value -initAmount.value)/initAmount.value).toFixed(2)
  }).then(res => {
    store.dispatch('getUser')
  })
}
// 开始模拟
const startHandle = () => {
  randomHandle(() => {
    if (isStart.value) {
      return
    }
    if (baseInfo.value.score <= 0) {
      return notify('积分不够！', 'error');
    }
    isStart.value = true
    tradeList.value = []
    tradeNum.value = 100
    amount.value = initAmount.value
    // 获取数据
    getRequestData({code: stockCode.value, type: typeValue.value}, (data) => {
      if (data.klines && data.klines.length > n) {

        let index = 120
        // 随机选择数据
        let offset = Math.floor(Math.random() * (data.klines.length - n))
        oldLines.value = data.klines.slice(offset, offset + n)
        kLines.value = oldLines.value.slice(0, index)
        currentLine.value = new CLCandlestick().klineToLines([kLines.value[kLines.value.length - 1]], 0)[0]
        nextTick(() => {

          const echartsData = new CLCandlestick(kLines.value, {pageSize: 0, isJoinShow: false, isLineShow: true, isSegmentShow: true}).getData()
          const option = new EchartsOption(echartsData, {pageSize: 0, isJoinShow: false, isShowX: false}).getOption()

          echartsRef.value.setEchartsOption(option)

          timer.value = setInterval(() => {
            if (kLines.value.length >= oldLines.value.length) {
              clearInterval(timer.value)
              timer.value = null
              isStart.value = false
              // 训练结束卖出全部
              if (stockNum.value > 0) {
                tradeNum.value = stockNum.value
                sellHandle()
              }
              // 保存训练数据
              saveTrain()
            } else {
              kLines.value.push(oldLines.value[index])
              currentLine.value =  new CLCandlestick().klineToLines([oldLines.value[index]])[0]

              const echartsData = new CLCandlestick(kLines.value, {pageSize: 0, isJoinShow: false,  isLineShow: true, isSegmentShow: true}).getData()
              const option = new EchartsOption(echartsData, {pageSize: 0, isJoinShow: false, isShowX: false}).getOption()

              echartsRef.value.setEchartsOption(option)
              index++
            }
          }, speed.value * 1000)
        })
      } else {
        // notify('训练数据不足，请更换股票代码', 'error')
        isStart.value = false
        startHandle()
      }
    })

  })
}

// 买入
const buyHandle = () => {
  if (currentLine.value) {
    const tradeAmount = tradeNum.value * currentLine.value.close
    if (tradeAmount > amount.value) {
      notify('可用金额不足', 'error')
    } else {
      amount.value -= tradeAmount
      stockNum.value += parseInt(tradeNum.value)
      notify('买入成功', 'success')

      tradeList.value.push({
        tradeDate: currentLine.value.date,
        price: currentLine.value.close,
        num: parseInt(tradeNum.value),
        type: 1
      })
    }
  }
}
// 卖出
const sellHandle = () => {
  if (currentLine.value) {
    const tradeAmount = tradeNum.value * currentLine.value.close

    if (tradeNum.value > stockNum.value) {
      notify('卖出数量不足', 'error')
    } else {
      amount.value += tradeAmount
      stockNum.value -= parseInt(tradeNum.value)
      notify('卖出成功', 'success')
      tradeList.value.push({
        tradeDate: currentLine.value.date,
        price: currentLine.value.close,
        num: parseInt(tradeNum.value),
        type: 2
      })
    }
  }

}
const randomHandle = (cb) => {
  const stockList = sessionStorage.getItem('stockList')
  if (stockList) {
    let arr = JSON.parse(stockList)
    stockCode.value = arr[Math.floor(Math.random() * arr.length)].stockCode
    if (cb) {
      cb()
    }
  } else {
    GET("/market/market/list", {}).then(res => {
      let arr = filterStockList(res.data)
      sessionStorage.setItem('stockList', JSON.stringify(arr))
      stockCode.value = arr[Math.floor(Math.random() * arr.length)].stockCode
      if (cb) {
        cb()
      }
    }).catch(() => {

    })
  }

}
</script>

<template>
  <div class="train">

    <c-card class="left">
      <div class="start" v-if="!isStart">
        <span @click="startHandle">开始训练</span>
      </div>
      <template  v-else>
        <c-echarts-stock ref="echartsRef" style="height: 800px;"></c-echarts-stock>
      </template>

    </c-card>
    <c-card class="right">
      <el-form>
        <el-form-item label="级别">
          <el-select
              v-model="typeValue"
              placeholder="请选择"
          >
            <el-option
                v-for="item in typeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="频率(秒)">
          <el-input-number v-model="speed" :min="1"/>
        </el-form-item>
        <el-form-item label="初始">
          <c-text class="w">{{initAmount}}</c-text>
        </el-form-item>
        <el-form-item label="可用">
          <c-text class="w">{{amount}}</c-text>
        </el-form-item>
        <el-form-item label="持仓">
          <c-text class="w">{{stockNum}}</c-text>
        </el-form-item>
        <el-form-item label="可买">
          <c-text class="w">{{availablePurchase}}</c-text>
        </el-form-item>
        <el-form-item label="交易量">
          <el-input-number v-model="tradeNum" :min="100" :step="100" />
        </el-form-item>
        <el-form-item>
          <el-button :disabled="!isStart" type="danger" @click="buyHandle">买入</el-button>
          <el-button :disabled="!isStart" type="success" @click="sellHandle">卖出</el-button>
        </el-form-item>
      </el-form>
      <p class="tip">说明：每次训练消耗1点积分</p>
      <el-table :data="tradeList" stripe highlight-current-row height="350px">
        <el-table-column prop="tradeDate" label="时间"/>
        <el-table-column prop="type" label="类型">
          <template #default="{row}">
            <el-text v-if="row.type === 1" type="danger">买</el-text>
            <el-text v-if="row.type === 2" type="success">卖</el-text>
          </template>
        </el-table-column>
        <el-table-column prop="price" label="价格"/>
      </el-table>
    </c-card>
  </div>

</template>

<style scoped lang="scss">
.train {
  display: flex;
  height: 100%;
  background: #f5f5f5;
  overflow: hidden;
  .left{
    flex: 1;
    margin-bottom: 0;
  }
  .right{
    width: 350px;
    margin-bottom: 0;
    margin-left: 10px;
  }
}
.start{
  height: 800px;
  display: flex;
  justify-content: center;
  align-items: center;
  span{
    display: inline-block;
    width: 150px;
    height: 150px;
    line-height: 150px;
    text-align: center;
    border-radius: 50%;
    background-color: #cb2020;
    color: #FFFFFF;
    cursor: pointer;
    font-size: 20px;
  }
}
</style>
